﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Telerik.Web.Mvc;

namespace Presentation.Web.Admin.Controllers
{
    [HandleError]
    public class PermissionController : Infrastructure.Crosscutting.NetFramework.Controllers.BaseController
    {
        #region helper service

        Infrastructure.Crosscutting.Authorize.IInitPermissionService initPermissionService;

        #endregion

        #region permission

        Infrastructure.Crosscutting.Authorize.IMvcActionService actionService;

        Infrastructure.Crosscutting.Authorize.IMvcActionClassService actionClaService;

        Infrastructure.Crosscutting.Authorize.IMvcControllerClassService controllerClaService;

        Infrastructure.Crosscutting.Authorize.IMvcControllerService controllerService;

        #endregion

        public PermissionController(Infrastructure.Crosscutting.NetFramework.IWorkContext work,
            Infrastructure.Crosscutting.Authorize.IInitPermissionService initPermission,
            Infrastructure.Crosscutting.Authorize.IMvcActionService action,
            Infrastructure.Crosscutting.Authorize.IMvcActionClassService actionClass,
            Infrastructure.Crosscutting.Authorize.IMvcControllerService controller,
            Infrastructure.Crosscutting.Authorize.IMvcControllerClassService controllerClass)
            : base(work)
        {
            if (initPermission == null)
            {
                throw new ArgumentNullException("initPermissionService is null");
            }
            if (action == null)
            {
                throw new ArgumentNullException("actionService is null");
            }
            if (actionClass == null)
            {
                throw new ArgumentNullException("actionClassService is null");
            }
            if (controller == null)
            {
                throw new ArgumentNullException("controllerService is null");
            }
            if (controllerClass == null)
            {
                throw new ArgumentNullException("controllerClassService is null");
            }
            initPermissionService = initPermission;
            actionService = action;
            actionClaService = actionClass;
            controllerService = controller;
            controllerClaService = controllerClass;
        }

        #region permission

        #region installed permission

        public ViewResult Index()
        {
            var data = initPermissionService.GetInstalledPermission();
            return View(data);
        }

        [GridAction]
        public JsonResult AjaxInstall(string searchKey, int? controllerId)
        {
            var data = initPermissionService.GetInstalledPermission();
            if (controllerId.HasValue && controllerId.Value > 0)
            {
                var temp = (int)controllerId;
                data = data.Where(e => e.ControllerId == temp).ToList();
            }
            if (!string.IsNullOrEmpty(searchKey))
            {
                data = data.Where(e => e.ActionName.ToLower().Contains(searchKey.ToLower())).ToList();
            }
            var model = new GridModel<Infrastructure.Crosscutting.Authorize.Dto.MvcActionDto>
            {
                Data = data,
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [HttpGet]
        public ViewResult InEdit(int id)
        {
            var model = actionService.Get(id);
            if (model != null && model.Id > 0)
            {
                var controllerName = controllerService.GetList().Where(e => e.Id == model.ControllerId).Select(e => e.Name).FirstOrDefault();
                var actionClassList = this.GetMvcActionClassTrueState();
                ViewBag.controllername = controllerName;
                ViewBag.actionclasslist = actionClassList;
            }
            return View(model.ToDto());
        }

        [HttpPost]
        public JsonResult InEdit(Domain.Dto.MvcActionDto dto)
        {
            var res = false;
            var message = "";
            var model = actionService.Get(dto.Id);
            if (model != null && model.Id > 0)
            {
                model.Remark = dto.Remark;
                model.ClassId = dto.ClassId;
                //model.State = dto.State;
                //model.SortNum = dto.SortNum;
                actionService.Modify(model, this.WorkContext.CurrentUser);
                res = true;
                var controllerName = controllerService.GetList().Where(e => e.Id == model.ControllerId).Select(e => e.Name).FirstOrDefault();
                var actionClassList = this.GetMvcActionClassTrueState();
                ViewBag.controllername = controllerName;
                ViewBag.actionclasslist = actionClassList;
            }
            else
            {
                message = "修改失败了啊！！！";
            }
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        [GridAction]
        [HttpPost]
        public JsonResult InDelete(int id)
        {
            var delete = actionService.Get(id);
            if (delete != null)
            {
                actionService.DeleteTrue(delete, this.WorkContext.CurrentUser);
            }
            var data = initPermissionService.GetInstalledPermission();
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        public JsonResult InMulDelete(FormCollection del)
        {
            var res = false;
            var message = "";
            var delete = del.GetValues("selectRow");
            foreach (var item in delete)
            {
                //在这里，我们做物理删除，方便以后添加，以便以后添加时做判断是否已经存在这个权限了
                res = actionService.DeleteTrue(delete.ToIntList(), this.WorkContext.CurrentUser);
                message = res == true ? "" : "删除操作貌似没有成功";
            }
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        public JsonResult SearchInstall(string term)
        {
            var model = initPermissionService.GetInstalledPermission();
            var data = model.Where(e => e.ActionName.ToLower().Contains(term.ToLower()))
                .Select(e => e.ActionName).Distinct().Take(10);
            return Json(data.ToList(), JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region uninstall permission

        public ViewResult Uninstall()
        {
            var model = initPermissionService.GetUninstallPermission();
            return View(model);
        }

        [GridAction]
        public JsonResult AjaxUninstall(string searchKey, int? controllerId)
        {
            var data = initPermissionService.GetUninstallPermission();
            if (controllerId.HasValue && controllerId.Value > 0)
            {
                var temp = (int)controllerId;
                data = data.Where(e => e.ControllerId == temp).ToList();
            }
            if (!string.IsNullOrEmpty(searchKey))
            {
                data = data.Where(e => e.ActionName.ToLower().Contains(searchKey.ToLower())).ToList();
            }
            var model = new GridModel<Infrastructure.Crosscutting.Authorize.Dto.MvcActionDto>
            {
                Data = data,
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [HttpPost]
        public JsonResult MulInstall(FormCollection mul)
        {
            var installPerList = mul.GetValues("selectRow");
            var operuser = this.WorkContext.CurrentUser;
            var res = false;
            var message = "";
            try
            {
                foreach (var item in installPerList)
                {
                    #region add permission

                    var temp = item.Split('|');
                    if (temp.Length == 2)
                    {
                        var strAction = string.IsNullOrEmpty(temp[0]) ? "" : temp[0].Trim();
                        var strController = string.IsNullOrEmpty(temp[1]) ? "" : temp[1].Trim();

                        #region id add
                        //如果当前的这个controller 存在
                        var currentController = controllerService.GetList().Where(e => e.AssemblyFullName == strController).FirstOrDefault();
                        if (currentController != null)
                        {
                            #region checked is added
                            //在这个controller 下找到当前要安装的action , 如果安装了，则进行下一个安装
                            var isAdded = actionService.GetList().Where(e => e.ControllerId == currentController.Id && e.Name == strAction).Any();
                            if (isAdded)
                            {
                                continue;
                            }
                            #endregion
                        }
                        #endregion
                        var addAction = new Domain.Entity.MvcAction();

                        #region controller name

                        var conFullNameList = strController.Split('.');
                        var conName = conFullNameList[conFullNameList.Length - 1];
                        conName = string.IsNullOrEmpty(conName) ? "" : conName.ToLower().Replace("controller", "");

                        #endregion

                        addAction.AddTime = System.DateTime.Now;

                        #region action cla id

                        var actionClaId = 0;
                        if (conFullNameList.Contains("Open"))
                        {
                            actionClaId = actionClaService.GetList().Where(e => e.Remark.ToLower().IndexOf(conName) >= 0)
                                .Where(e => e.Remark.ToLower().IndexOf("interface") >= 0)
                                .Select(e => e.Id).FirstOrDefault();
                        }
                        else
                        {
                            actionClaId = actionClaService.GetList().Where(e => e.Remark.ToLower().IndexOf(conName) >= 0)
                                .Where(e => e.Remark.ToLower().IndexOf("interface") < 0)
                                .Select(e => e.Id).FirstOrDefault();
                        }
                        addAction.ClassId = actionClaId;

                        #endregion

                        addAction.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                        addAction.Name = strAction;
                        addAction.Remark = strAction;
                        addAction.SortNum = 0;
                        addAction.State = true;
                        //在这里先赋一次值好一些，
                        addAction.ControllerId = 0;
                        if (currentController != null)
                        {
                            addAction.ControllerId = currentController.Id;
                        }
                        else
                        {
                            var addController = new Domain.Entity.MvcController();
                            addController.AddTime = System.DateTime.Now;
                            addController.AssemblyFullName = strController;

                            #region  controller  cla id

                            var conCla = 0;
                            if (conFullNameList.Contains("Open"))
                            {
                                conCla = controllerClaService.GetList().Where(e => e.Remark.ToLower().IndexOf(conName) >= 0)
                                    .Where(e => e.Remark.ToLower().IndexOf("interface") >= 0)
                                    .Select(e => e.Id).FirstOrDefault();
                            }
                            else
                            {
                                conCla = controllerClaService.GetList().Where(e => e.Remark.ToLower().IndexOf(conName) >= 0)
                                    .Where(e => e.Remark.ToLower().IndexOf("interface") < 0)
                                    .Select(e => e.Id).FirstOrDefault();
                            }
                            addController.ClassId = conCla;

                            #endregion

                            addController.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                            addController.Name = strController;
                            addController.Remark = strController;
                            addController.SortNum = 0;
                            addController.State = true;
                            controllerService.Add(addController, operuser);
                            addAction.ControllerId = addController.Id;
                        }
                        actionService.Add(addAction, operuser);
                    }
                    #endregion
                }
                res = true;
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        public JsonResult SearchUninstall(string term)
        {
            var model = initPermissionService.GetUninstallPermission();
            var data = model.Where(e => e.ActionName.ToLower().Contains(term.ToLower()))
                .Select(e => e.ActionName).Distinct().Take(10);
            return Json(data.ToList(), JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region init permission

        [HttpGet]
        public ViewResult Init()
        {
            return View();
        }

        [HttpPost]
        public JsonResult InitAll(string rand)
        {
            var res = initPermissionService.AddAssemblyPermissionToDb();
            var message = res == true ? "" : "初始化系统权限失败了T_T";
            return Json(new { success = res, message = message });
        }

        [HttpPost]
        public JsonResult InitAdminPermission(string rand)
        {
            var message = "";
            var res = initPermissionService.InitAdminPermission(message);
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult InitSystemUserPermission(string rand)
        {
            var message = "";
            var res = initPermissionService.InitSystemUserPermission(message);
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult InitOpenUserPermission(string rand)
        {
            var message = "";
            var res = initPermissionService.InitOpenUserPermission(message);
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        #endregion

        #endregion

        #region controller info

        [HttpGet]
        public ViewResult ControllerList()
        {
            var data = this.GetMvcControllerTrueState();
            return View(data.ToDto());
        }

        [GridAction]
        public JsonResult AjaxControllerList(string searchKey)
        {
            var data = this.GetMvcControllerTrueState();
            if (!string.IsNullOrEmpty(searchKey))
            {
                data = data.Where(e => e.Remark.Contains(searchKey));
            }
            var model = new GridModel<Domain.Dto.MvcControllerDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [HttpGet]
        public ViewResult ControllerInfo(int id)
        {
            ViewBag.controllerclass = controllerClaService.GetList();
            var model = controllerService.Get(id);
            if (model != null)
            {
                var dto = model.ToDto();
                return View(dto);
            }
            return View(model);
        }

        [HttpPost]
        public JsonResult ControllerInfo(Domain.Dto.MvcControllerDto dto)
        {
            var res = false;
            var message = "";
            ViewBag.controllerclass = controllerClaService.GetList();
            if (dto.Id > 0 && dto != null)
            {
                var entity = controllerService.Get(dto.Id);
                if (entity != null)
                {
                    entity.Remark = dto.Remark;
                    entity.ClassId = dto.ClassId;
                    controllerService.Modify(entity, this.WorkContext.CurrentUser);
                    res = true;
                }
                else
                {
                    message = "没有找到，你要修改的对象！";
                }
            }
            message = res ? "修改成功" : "操作失败了T_T";
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        public JsonResult SearchController(string term)
        {
            var data = this.GetMvcControllerTrueState();
            if (!string.IsNullOrEmpty(term))
            {
                data = data.Where(e => e.Remark.Contains(term.Trim()));
            }
            var model = data.Select(e => e.Remark).Distinct().Take(10);
            return Json(model.ToList(), JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region permission class

        public ViewResult PermissionClass()
        {
            var data = this.GetMvcActionClassTrueState();
            var model = data.ToDto();
            return View(model);
        }

        [GridAction]
        public JsonResult AjaxPermissionClass(string searchKey)
        {
            var data = this.GetMvcActionClassTrueState().AsQueryable();
            if (!string.IsNullOrEmpty(searchKey))
            {
                data = data.Where(e => e.Name.Contains(searchKey.Trim()));
            }
            var model = new GridModel<Domain.Dto.MvcActionClassDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [GridAction]
        [HttpPost]
        public JsonResult AddPermissionClass(Domain.Dto.MvcActionClassDto dto)
        {
            if (!string.IsNullOrEmpty(dto.Name))
            {
                dto.AddTime = System.DateTime.Now;
                dto.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                dto.State = true;
                var model = dto.ToEntity();
                actionClaService.Add(model, this.WorkContext.CurrentUser);
            }
            var data = this.GetMvcActionClassTrueState();
            var res = new GridModel<Domain.Dto.MvcActionClassDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = res, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [GridAction]
        [HttpPost]
        public JsonResult DeletePermissionClass(int id)
        {
            var delete = actionClaService.Get(id);
            if (delete != null)
            {
                actionClaService.DeleteTrue(delete, this.WorkContext.CurrentUser);
            }
            var data = this.GetMvcActionClassTrueState();
            return Json(data.ToDto(), JsonRequestBehavior.AllowGet);
        }

        public JsonResult MulDeletePermissionClass(FormCollection del)
        {
            var res = false;
            var message = "";
            var delete = del.GetValues("selectRow");
            foreach (var item in delete)
            {
                //在这里，我们做物理删除，方便以后添加，以便以后添加时做判断是否已经存在这个权限了
                res = actionClaService.DeleteTrue(delete.ToIntList(), this.WorkContext.CurrentUser);
                message = res == true ? "" : "删除操作貌似没有成功";
            }
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        [GridAction]
        [HttpPost]
        public JsonResult EditPermissionClass(Domain.Dto.MvcActionClassDto dto)
        {
            if (dto.Id > 0)
            {
                var entity = actionClaService.Get(dto.Id);
                if (entity != null)
                {
                    entity.Name = dto.Name;
                    entity.Remark = dto.Remark;
                    var res = actionClaService.Modify(entity, this.WorkContext.CurrentUser);
                }
            }
            var data = this.GetMvcActionClassTrueState();
            var model = new GridModel<Domain.Dto.MvcActionClassDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }


        public JsonResult SearchPermissionClass(string term)
        {
            var data = this.GetMvcActionClassTrueState();
            if (!string.IsNullOrEmpty(term))
            {
                data = data.Where(e => e.Name.Contains(term.Trim()));
            }
            var model = data.Select(e => e.Name).Distinct().Take(10);
            return Json(model.ToList(), JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region controller class

        public ViewResult ControllerClass()
        {
            var model = this.GetMvcControllerClassTrueState();
            return View(model.ToDto());
        }

        [GridAction]
        [HttpPost]
        public JsonResult AjaxControllerClass(string searchKey)
        {
            var data = this.GetMvcControllerClassTrueState();
            if (!string.IsNullOrEmpty(searchKey))
            {
                data = data.Where(e => e.Name.Contains(searchKey));
            }
            var model = new GridModel<Domain.Dto.MvcControllerClassDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [GridAction]
        [HttpPost]
        public JsonResult AddControllerClass(Domain.Dto.MvcControllerClassDto dto)
        {
            if (!string.IsNullOrEmpty(dto.Name))
            {
                dto.AddTime = System.DateTime.Now;
                dto.State = true;
                dto.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                var model = dto.ToEntity();
                controllerClaService.Add(model, this.WorkContext.CurrentUser);
            }
            var data = this.GetMvcControllerClassTrueState();
            var res = new GridModel<Domain.Dto.MvcControllerClassDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = res, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [GridAction]
        [HttpPost]
        public JsonResult DeleteControllerClass(int id)
        {
            var delete = controllerClaService.Get(id);
            if (delete != null)
            {
                controllerClaService.DeleteTrue(delete, this.WorkContext.CurrentUser);
            }
            var data = this.GetMvcControllerClassTrueState();
            return Json(data.ToDto(), JsonRequestBehavior.AllowGet);
        }

        public JsonResult MulDeleteControllerClass(FormCollection del)
        {
            var res = false;
            var message = "";
            var delete = del.GetValues("selectRow");
            foreach (var item in delete)
            {
                //在这里，我们做物理删除，方便以后添加，以便以后添加时做判断是否已经存在这个权限了
                res = controllerClaService.DeleteTrue(delete.ToIntList(), this.WorkContext.CurrentUser);
                message = res == true ? "" : "删除操作貌似没有成功";
            }
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        [GridAction]
        [HttpPost]
        public JsonResult EditControllerClass(Domain.Dto.MvcControllerClassDto dto)
        {
            if (dto.Id > 0)
            {
                var entity = controllerClaService.Get(dto.Id);
                if (entity != null)
                {
                    entity.Name = dto.Name;
                    entity.Remark = dto.Remark;
                    var res = controllerClaService.Modify(entity, this.WorkContext.CurrentUser);
                }
            }
            var data = this.GetMvcControllerClassTrueState();
            var model = new GridModel<Domain.Dto.MvcControllerClassDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        public JsonResult SearchControllerClass(string term)
        {
            var data = this.GetMvcControllerClassTrueState();
            if (!string.IsNullOrEmpty(term))
            {
                data = data.Where(e => e.Name.Contains(term.Trim()));
            }
            var model = data.Select(e => e.Name).Distinct().Take(10);
            return Json(model.ToList(), JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region util

        protected IQueryable<Domain.Entity.MvcController> GetMvcControllerTrueState()
        {
            var data = controllerService.GetList().OrderBy(e => e.AssemblyFullName).AsQueryable();
            return data;
        }

        protected IQueryable<Domain.Entity.MvcControllerClass> GetMvcControllerClassTrueState()
        {
            var data = controllerClaService.GetList().Where(e => e.State == true)
                .OrderByDescending(e => e.Id).AsQueryable();
            return data;
        }

        protected IQueryable<Domain.Entity.MvcActionClass> GetMvcActionClassTrueState()
        {
            var data = actionClaService.GetList().Where(e => e.State == true)
                .OrderByDescending(e => e.Id).AsQueryable();
            return data;
        }

        #endregion
    }
}
